﻿using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;

namespace UCS.XNA.CombatBiplanes.Synchronization
{
    public class ClientGameSynchronizer : GameSynchronizer
    {
        #region Private Members

        private bool _receive;

        #endregion

        #region Constructors

        public ClientGameSynchronizer()
        {
            this._connectedClients = new Dictionary<Player, TcpClient>();
            this._playersBuffers = new Dictionary<Player, byte[]>();
            this._playersTotalBytesReceived = new Dictionary<Player, int>();
        }

        #endregion

        #region Public Methods

        public void Connect(string serverAddress)
        {
            try
            {
                Player player = new Player(1, 3);
                this._connectedClients.Add(player, new TcpClient(serverAddress, SERVER_PORT));
                this._playersBuffers.Add(player, new byte[5]);
                this._playersTotalBytesReceived.Add(player, 0);

                this._receive = true;
            }
            catch (SocketException ex)
            {
                throw new EstabilishConnectionFailedException(ex.Message.Replace("ã", "a").Replace("é", "e"));
            }
        }

        #endregion

        #region Overriden Methods

        public override void Update(GameTime gameTime)
        {
            foreach (byte[] command in this.ReceiveCommand())
            {
                if (command != null)
                {
                    ActionType actionType = this.Converter.ToActionType(command);
                    IActionExecutor executor = this.Converter.ToActionExecutor(command);
                    int[] parameters = this.Converter.ToParameter(command);

                    executor.Execute(actionType, parameters);
                }
            }
        }

        public override void SendActionToEveryone(ActionType actionType, IActionExecutor executor, int[] parameters)
        {
            if (actionType == ActionType.Angle || actionType == ActionType.Fire)
            {
                byte[] command = this.Converter.ToCommand(actionType, executor, parameters);

                this.SendCommand(this._connectedClients.Values.First(), command);
            }
        }

        protected override void SendActionToPlayer(Player player, ActionType actionType, IActionExecutor executor, int[] parameters)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}
